package com.yc.framework.web.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yc.common.exceptions.ServiceException;
import com.yc.common.constant.Constants;
import com.yc.common.core.domain.entity.SysUser;
import com.yc.common.exceptions.user.UserDeleteException;
import com.yc.common.exceptions.user.UserDisabledException;
import com.yc.common.exceptions.user.UserNotExistsException;
import com.yc.common.utils.StringUtil;
import com.yc.framework.manager.AsyncManager;
import com.yc.framework.manager.factory.AsyncFactory;
import com.yc.framework.security.context.AuthenticationContextHolder;
import com.yc.system.mapper.SysUserMapper;
import com.yc.common.enums.UserStatus;
import com.yc.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysPasswordService passwordService;

    @Autowired
    private ISysUserService sysUserService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 使用手机号查询用户
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getPhonenumber, username);
        SysUser user = sysUserMapper.selectOne(queryWrapper);

        // 如果没有查询到用户
        if (StringUtil.isNull(user)) {
            log.info("登录用户：{} 不存在.", username);
            throw new UserNotExistsException();
        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            log.info("登录用户：{} 已被禁用.", username);
            throw new UserDisabledException();
        } else if (UserStatus.DELETED.getCode().equals(user.getUserType())) {
            log.info("登录用户：{} 已被删除.", username);
            throw new UserDeleteException();
        }

        try {
            // 获取认证上下文中的密码
            String password = (String) AuthenticationContextHolder.getContext().getCredentials();

            // 使用SysPasswordService的validate方法进行验证
            // 此方法内部已经实现了密码错误次数控制和提示信息
            passwordService.validate(user, password);

            // 密码验证成功，记录登录成功日志
            AsyncManager.me().execute(AsyncFactory.recordLoginInfo(
                    username, Constants.LOGIN_SUCCESS, "登录成功"));

        } catch (ServiceException e) {
            // 捕获ServiceException并记录日志，这是从passwordService.validate抛出的异常
            AsyncManager.me().execute(AsyncFactory.recordLoginInfo(
                    username, Constants.LOGIN_FAIL, e.getMessage()));
            throw e; // 重新抛出异常，包含了尝试次数信息
        } catch (Exception e) {
            // 其他异常记录并重新抛出
            log.error("验证密码异常:", e);
            AsyncManager.me().execute(AsyncFactory.recordLoginInfo(
                    username, Constants.LOGIN_FAIL, e.getMessage()));
            throw new ServiceException("登录验证异常: " + e.getMessage());
        }

        // 在这里只返回用户信息
        return sysUserService.createLoginUser(user.getId());
    }

}